// Author: Domien Nowicki, Bjorn Schobben

#include "TextureManagerModel.h"
#include <QBrush>
#include <QIcon>
#include <QPainter>
#include <QPalette>


TextureManagerModel::TextureManagerModel(QObject *parent): QAbstractListModel(parent)
{
	// Generate empty texture thumb image
	emptyTextureThumb = ConvertTextureToThumb( GetEmptyTexture() );
}

TextureManagerModel::~TextureManagerModel()
{
}

int TextureManagerModel::rowCount(const QModelIndex &parent) const
{
	return GetTextureCount();
}


int TextureManagerModel::columnCount(const QModelIndex &parent) const
{
	return 1;
}

QVariant TextureManagerModel::data(const QModelIndex &index, int role) const
{
	if (!index.isValid())
		return QVariant();

	if (index.row() >= GetTextureCount())
		return QVariant();

	const Texture& texture = GetTexture(index.row());

	if (role == Qt::BackgroundRole)
	{
		// Draw usercolor background for this texture item
		const Pixel& pixel = texture.GetUserColor();
		return QBrush(QColor(pixel.GetRed(), pixel.GetGreen(), pixel.GetBlue(), 150));
	}

	if (role == Qt::DecorationRole)
	{
		// Draw thumb image for texture
		return thumbTextures[index.row()];
	}

	if (role == Qt::DisplayRole)
	{
		const std::string& name = texture.GetName();

		// If texture has name, display it
		if (name.length())
		{
			return QString::fromStdString(name);
		}
		else
		{
			// otherwise just use default numbering
			return QString("Texture %1").arg(index.row());
		}
	}
	else
		return QVariant();
}

QVariant TextureManagerModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (role != Qt::DisplayRole)
		return QVariant();



	if (orientation == Qt::Horizontal)
		return QString("Texture");
	else
		return QString("%1").arg(section);
}

Qt::ItemFlags TextureManagerModel::flags(const QModelIndex &index) const
{
	if (!index.isValid())
		return Qt::ItemIsEnabled;

	return QAbstractItemModel::flags(index);
}

QPixmap TextureManagerModel::ConvertTextureToThumb(const Texture& texture)
{
	unsigned int width = texture.GetWidth();
	unsigned int height = texture.GetHeight();


	// Generate new empty image
	QImage image = QImage(width, height, QImage::Format_RGB32);


	// Fill in the pixels
	for(unsigned int y=0; y<height; y++)
	{
		for(unsigned int x=0; x<width; x++)
		{
			const Pixel& pixel = texture.GetPixel(x, y);

			image.setPixel(x, y, qRgb(pixel.GetRed(), pixel.GetGreen(), pixel.GetBlue()));
		}
	}

	// Scale to thumb size
	image = image.scaled(THUMBSIZE, THUMBSIZE);

	QPainter painter(&image);

	// Draw gray border
	QPen pen = painter.pen();
	painter.setPen(QPen(Qt::gray));
	painter.drawLine(QLine(0,0,0,THUMBSIZE-1));
	painter.drawLine(QLine(0,THUMBSIZE-1,THUMBSIZE-1,THUMBSIZE-1));
	painter.drawLine(QLine(THUMBSIZE-1,THUMBSIZE-1,THUMBSIZE-1,0));
	painter.drawLine(QLine(THUMBSIZE-1,0,0,0));
	painter.setPen(pen);


	return QPixmap::fromImage(image);
}

// Add texture to texturemanager and add thumb
unsigned int TextureManagerModel::AddTexture(const Texture& texture)
{
	unsigned int tindex = TextureManager::AddTexture(texture);


	beginInsertRows(QModelIndex(), tindex, tindex);

	thumbTextures.push_back( ConvertTextureToThumb(texture) );

	endInsertRows();

	emit modelUpdated();

	return tindex;
}

// Remove all textures and thumbs
void TextureManagerModel::Clear()
{
	beginRemoveRows(QModelIndex(), 0, GetTextureCount());
	TextureManager::Clear();
	thumbTextures.clear();
	endRemoveRows();

	emit modelUpdated();
}

// Remove a texture and its thumb
void TextureManagerModel::RemoveTexture(unsigned int index)
{
	TextureManager::RemoveTexture(index);

	beginRemoveRows(QModelIndex(), index, index);

	thumbTextures.erase( thumbTextures.begin() + index );

	endRemoveRows();

	emit modelUpdated();
}

// Return a thumb of the texture
const QPixmap& TextureManagerModel::GetTextureThumb(unsigned int tindex) const
{ 
	if (-1 == tindex)
		return emptyTextureThumb;
	else
		return thumbTextures[tindex];
}